package com.wzp.fulfill.application.command.executor;

import com.wzp.fulfill.application.command.OrderFulfillCommand;
import com.wzp.fulfill.application.command.dto.OrderDTO;
import com.wzp.fulfill.application.converter.FulfillOrderConverter;
import com.wzp.fulfill.domain.event.OrderInterceptedEvent;
import com.wzp.fulfill.domain.model.fulfillorder.FulfillOrder;
import com.wzp.fulfill.domain.gateway.DomainEventGateway;
import com.wzp.fulfill.domain.gateway.FulfillOrderGateway;
import com.wzp.fulfill.domain.gateway.RiskControlApiGateway;
import com.wzp.fulfill.domain.gateway.WarehouseApiGateway;
import com.wzp.fulfill.domain.service.LogisticsDomainService;
import com.wzp.fulfill.domain.service.WarehouseDomainService;
import com.wzp.fulfill.domain.model.warehouse.Warehouse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 订单履约命令（流程）的执行器
 */
@Component
public class OrderFulfillCommandExecutor {

    @Autowired
    private FulfillOrderConverter fulfillOrderConverter;
    @Autowired
    private FulfillOrderGateway fulfillOrderGateway;
    @Autowired
    private WarehouseDomainService warehouseDomainService;
    @Autowired
    private RiskControlApiGateway riskControlApiGateway;
    @Autowired
    private DomainEventGateway domainEventGateway;
    @Autowired
    private LogisticsDomainService logisticsDomainService;
    @Autowired
    private WarehouseApiGateway warehouseApiGateway;

    // 专门负责订单履约流程的编排，把这个流程按照战术建模的设计，完成落地开发
    public void execute(OrderFulfillCommand orderFulfillCommand) {
        // 第一步，保存订单，需要去使用履约订单仓储/gateway来进行保存
        OrderDTO orderDTO = orderFulfillCommand.getOrderDTO();
        FulfillOrder fulfillOrder = fulfillOrderConverter.convert(orderDTO);
        fulfillOrderGateway.save(fulfillOrder);

        // 第二步，预分仓
        Warehouse warehouse = warehouseDomainService.preAllocateWarehouse(fulfillOrder);

        // 第三步，风控拦截
        Boolean interceptResult = riskControlApiGateway.riskControlIntercept(fulfillOrder);
        if (!interceptResult) {
            // 如果被风控拦截了，此时就需要发布订单被拦截的领域事件，通知人工审核
            domainEventGateway.publishOrderInterceptedEvent(new OrderInterceptedEvent());
            return;
        }

        // 第四步，分物流
        logisticsDomainService.allocateLogistics(fulfillOrder, warehouse);

        // 第五步，下发库房
        warehouseApiGateway.sendFulfillOrder(fulfillOrder, warehouse);
    }

}
